// Copyright (c) 2023 Huawei Device Co., Ltd.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use core::fmt::{Debug, Display, Formatter};

/// `DomException`, which corresponds to the `Exception DOMException`.
///
/// # Association
/// [Exception DOMException](https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-17189187)
#[derive(Debug, Copy, Clone)]
pub enum DomException {
    /// If index or size is negative, or greater than the allowed value.
    IndexSizeErr = 1,

    /// If the specified range of text does not fit into a `DOMString`.
    DomstringSizeErr = 2,

    /// If the specified range of text does not fit into a `DOMString`.
    HierarchyRequestErr = 3,

    /// If a `Node` is used in a different document than the one that created it
    /// (that doesn't support it).
    WrongDocumentErr = 4,

    /// If an invalid or illegal character is specified, such as in an XML name.
    InvalidCharacterErr = 5,

    /// If data is specified for a `Node` which does not support data.
    NoDataAllowedErr = 6,

    /// If an attempt is made to modify an object where modifications are not allowed.
    NoModificationAllowedErr = 7,

    /// If an attempt is made to reference a `Node` in a context where it does not exist.
    NotFoundErr = 8,

    /// If the implementation does not support the requested type of object or operation.
    NotSupportedErr = 9,

    /// If an attempt is made to add an attribute that is already in use elsewhere.
    InuseAttributeErr = 10,

    /// If an attempt is made to use an object that is not, or is no longer, usable.
    InvalidStateErr = 11,

    /// If an invalid or illegal string is specified.
    SyntaxErr = 12,

    /// If an attempt is made to modify the type of the underlying object.
    InvalidModificationErr = 13,

    /// If an attempt is made to create or change an object in a way which is
    /// incorrect with regard to namespaces.
    NamespaceErr = 14,

    /// If a parameter or an operation is not supported by the underlying object.
    InvalidAccessErr = 15,

    /// If a call to a method such as `insertBefore` or `removeChild` would
    /// make the `Node` invalid with respect to "partial validity", this
    /// exception would be raised and the operation would not be done. This code
    /// is used in `[DOM Level 3 Validation]`. Refer to this specification for
    /// further information.
    ValidationErr = 16,

    /// If the type of an object is incompatible with the expected type of the
    /// parameter associated to the object.
    TypeMismatchErr = 17,
}

impl Display for DomException {
    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
        Debug::fmt(self, f)
    }
}

impl std::error::Error for DomException {}

#[cfg(test)]
impl PartialEq for DomException {
    fn eq(&self, other: &Self) -> bool {
        *self as usize == *other as usize
    }
}

#[cfg(test)]
mod ut_error {
    use crate::structure::DomException;
    /*
     * @title  UT test for dom display
     * @design Condition Coverage
     * @precon NA
     * @brief  1. Call DomException.
     *         2. Print DomException。
     *         3. Compare result
     * @expect 1. true。
     * @auto   yes
     */
    #[test]
    fn ut_dom_exception_display() {
        // Create a `Document`.
        let tmp = DomException::DomstringSizeErr;
        let res = format!("{tmp}");
        assert_eq!(res, "DomstringSizeErr");
    }
}
